feat: configurable home link for the workspace rail - #178
Conversation
Deployments that run ClickClack inside a larger product need the rail's home button to lead back to that product instead of the ClickClack landing page. CLICKCLACK_HOME_URL / CLICKCLACK_HOME_LABEL (home_url / home_label in the config file) set the destination and the short label; both keep their built-in defaults when unset. The API validates the URL as an absolute http(s) URL or an absolute path (never javascript: or protocol-relative), bounds the label, and serves the pair from the public GET /api/home-link. The shell reads it once at startup and renders it on the GuildRail home button; a failed or malformed response keeps the default. Embedded web assets rebuilt.
|
🦞👀 Pull request received. I will update this pull request when review starts. |
|
Evidence, continued (full
|
|
Codex review: needs real behavior proof before merge. Reviewed August 27, 2026, 8:03 PM ET / August 28, 2026, 00:03 UTC. ClawSweeper reviewWhat this changesThe PR adds optional home-link URL and label settings, exposes them through the API, and renders them in the workspace rail. Merge readiness⛔ Blocked until real behavior proof from a real setup is added - 13 items remain Keep this PR open: its focused implementation has three P2 correctness gaps and only test/CI evidence, not inspectable after-fix behavior proof. Priority: P3 Review scores
Verification
Live VerificationCommand: Result: PASS (completed) Assertions:
How this fits togetherThe server validates deployment configuration and serves a small home-link payload to the ClickClack web shell. The shell loads it at startup and supplies the destination and label to the workspace navigation rail. flowchart LR
A[Deployment settings] --> B[Server validation]
B --> C[Home-link API]
C --> D[Web shell startup]
D --> E[Desktop navigation guard]
D --> F[Workspace rail link]
Decision needed
Why: This PR adds permanent server configuration and a public endpoint; the mechanical fixes do not establish maintainer acceptance of that product contract. Before merge
Findings
Agent review detailsSecurityNeeds attention: The new deployment-configured link validator permits a browser URL-parsing bypass to an external host. Review metrics
Merge-risk optionsMaintainer options:
Copy recommended automerge instructionTechnical reviewBest possible solution: Preserve Do we have a high-confidence way to reproduce the issue? Yes. Current-head source deterministically routes an integrated desktop with a label-only setting to Is this the best way to solve the issue? No. The feature needs the three focused desktop and URL-validation corrections, plus maintainer confirmation that this new core configuration contract is desired. Full review comments:
Overall correctness: patch is incorrect AGENTS.md: found, but no applicable review policy affected this item. Codex review notes: model internal, reasoning high; reviewed against 27bcc19b1cbe. LabelsLabel changes:
Label justifications:
EvidenceSecurity concerns:
Acceptance criteria:
What I checked:
Likely related people:
Rating scale
Overall follows the weaker of proof and patch quality. Workflow
HistoryReview history (1 earlier review cycle)
|
What Problem This Solves
Deployments that run ClickClack inside a larger product (ours sits next to an internal operations app, behind Cloudflare Access) have a home button on the workspace rail that always leads to the ClickClack landing page and always reads
cc. For those users the landing page is a dead end; the button should lead back to the product they came from.Why This Change Was Made
Two optional server settings,
CLICKCLACK_HOME_URLandCLICKCLACK_HOME_LABEL(home_url/home_labelin the JSON config file), set the destination and the short label of that button. Both keep the built-in defaults (/,cc) when unset, so existing deployments do not change.config: the URL must be an absolutehttp(s)URL or an absolute path on this deployment;javascript:, protocol-relative and relative values are rejected atservevalidation. The label is trimmed and bounded (32 characters).httpapi: new publicGET /api/home-linkreturning{url, label}with defaults applied. It carries no user or workspace data.web:lib/home-link.tsloads and re-validates the payload field by field (a malformed or failed response keeps the default);GuildRailrenders the label and title; the desktop shell keeps its/apphome when the default is in use.docs/configuration.md: two new rows.User Impact
No change unless the settings are configured. With them, the rail's home button shows the product name and opens the product.
Evidence
go build ./...,go vet,gofmt -lclean.go test ./apps/api/internal/config/ ./apps/api/internal/httpapi/ -run 'TestNormalizeHomeLink|TestValidateServe|TestHomeLinkEndpoint|TestLoadDefaultsEnvAndFile': ok (defaults, absolute URL, absolute path, label-only, rejectedjavascript:///host/ relative / oversized label; endpoint defaults, configured, partial config).node --test src/lib/home-link.test.ts: 4 pass (default fallback, accepted shapes, field-by-field rejection, failed fetch fallback).pnpm typecheck(web),pnpm lint,pnpm fmt:check: clean.pnpm test(web tests + web/sdk build + Go suite with the rebuilt dist): running at the time of opening; result appended below.